Threejs 基础模板

2022-03-01 ThreejsWebGL

# Threejs 基础模板

Threejs 基础模板

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>threejs基础模板</title>
		<style type="text/css">
			* {
				padding: 0;
				margin: 0;
			}
		</style>
	</head>
	<body>
	</body>
	<!-- threejs基础包依赖 -->
	<script src="https://cdn.bootcdn.net/ajax/libs/three.js/0.144.0/three.min.js"></script>
	<script type="text/javascript">		
		// 1.新建场景
		const scene = new THREE.Scene();
		
		// 2.新建照相机, 把照相机添加到场景中(照相机也是特殊的物体)
		const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
		scene.add(camera);
		
		// 3.新建物体(形状,材质), 把物体添加到场景中
		const boxShape = new THREE.BoxGeometry(1,1,1);
		const boxMaterical = new THREE.MeshBasicMaterial({color: 0xffff00 });
		const boxMesh = new THREE.Mesh(boxShape, boxMaterical);
		scene.add(boxMesh);
		// boxMesh.position.set(0, 0, 3);
		
		camera.position.set(0,0, 3); // 设置相机的位置, 至关重要; 默认 scene.add(), 会将物体添加到 (0,0,0)
		
		// 4.新建渲染器, 设置渲染器的大小
		const renderer = new THREE.WebGLRenderer();
		renderer.setSize(window.innerWidth, window.innerHeight);
		
		// 5.把渲染器的的DOM节点挂载倒视图
		document.body.appendChild(renderer.domElement);
		
		// 6.启动渲染器
		// renderer.render(scene, camera);
		// 请求下一帧的动画(优化, 按需渲染 减少不必要的渲染 例如 监听用户鼠标缩放 拖拽事件 当用户鼠标发生交互才进行渲染)
		function animate() {
		    requestAnimationFrame( animate );
		
		    boxMesh.rotation.x += 0.01;
		    boxMesh.rotation.y += 0.01;
		
		    renderer.render( scene, camera );
		};
		
		animate();
	</script>
</html>

1_base_template

# threejs 如何渲染一个模型

threejs渲染流程

threejs渲染

物体

# 控制渲染帧率

控制渲染帧率

  • 参考链接
    • Threejs 控制渲染帧率
      • http://www.yanhuangxueyuan.com/doc/Three.js/FrameNumber.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>控制渲染帧率</title>
		<style type="text/css">
			* {
				padding: 0;
				margin: 0;
			}
		</style>
	</head>
	<body>
	</body>
	<!-- threejs基础包依赖 -->
	<script src="https://cdn.bootcdn.net/ajax/libs/three.js/0.144.0/three.min.js"></script>
	<!-- 挂载相关提示信息的状态组件 -->
	<script src="https://cdn.jsdelivr.net/npm/three@0.144.0/examples/js/libs/stats.min.js"></script>
	<script type="text/javascript">		
		// 1.新建场景
		const scene = new THREE.Scene();
		
		// 2.新建照相机, 把照相机添加到场景中(照相机也是特殊的物体)
		const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
		scene.add(camera);
		
		// 3.新建物体(形状,材质), 把物体添加到场景中
		const boxShape = new THREE.BoxGeometry(1,1,1);
		const boxMaterical = new THREE.MeshBasicMaterial({color: 0xffff00 });
		const boxMesh = new THREE.Mesh(boxShape, boxMaterical);
		scene.add(boxMesh);
		// boxMesh.position.set(0, 0, 3);
		
		camera.position.set(0,0, 3); // 设置相机的位置, 至关重要; 默认 scene.add(), 会将物体添加到 (0,0,0)
		
		// 4.新建渲染器, 设置渲染器的大小
		const renderer = new THREE.WebGLRenderer();
		renderer.setSize(window.innerWidth, window.innerHeight);
		
		// 5.把渲染器的的DOM节点挂载倒视图
		document.body.appendChild(renderer.domElement);
		
		// 添加fps提示
		function initStatus() {
		    const stats = new Stats();
		    //设置统计模式
		    // stats.setMode(); // 0: fps, 1: ms 2: memory
		    //统计信息显示在左上角
		    stats.domElement.style.position = 'fixed';
		    stats.domElement.style.left = '0px';
		    stats.domElement.style.top = '0px';
		    //将统计对象挂载到对应的元素中
		    document.body.appendChild(stats.domElement);
		    return stats;
		};
		const stats = initStatus(); //添加fps提示
		
		// 创建一个时钟对象Clock
		const clock = new THREE.Clock();
		// 设置渲染频率为30FBS,也就是每秒调用渲染器render方法大约30次
		const FPS = 30;
		const renderT = 1 / FPS; //单位秒  间隔多长时间渲染渲染一次
		// 声明一个变量表示render()函数被多次调用累积时间
		// 如果执行一次renderer.render,timeS重新置0
		let timeS = 0;
		
		// 6.启动渲染器, 请求下一帧的动画;限制渲染的帧率
		function animate() {
		  requestAnimationFrame(animate);
		  // clock.getDelta()方法获得两帧的时间间隔
		  const T = clock.getDelta();
		  timeS = timeS + T;
		  // requestAnimationFrame默认调用render函数60次,通过时间判断,降低renderer.render执行频率
		  if (timeS > renderT) {
		    // 控制台查看渲染器渲染方法的调用周期,也就是间隔时间是多少
		  //   console.log(`调用.render时间间隔`,timeS*1000+'毫秒');
		    renderer.render(scene, camera); //执行渲染操作
		    stats.update();
		
		    // renderer.render每执行一次,timeS置0
		    timeS = 0;
		  }
		}
		
		
		animate();
	</script>
</html>


1_limitFPS

# 添加轨道控制器

添加轨道控制器

  • 参考链接
    • Threejs 轨道控制器
      • https://threejs.org/docs/index.html?q=controls#examples/zh/controls/OrbitControls


<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>添加轨道控制器</title>
		<style type="text/css">
			* {
				padding: 0;
				margin: 0;
			}
		</style>
	</head>
	<body>
	</body>
	<!-- threejs基础包依赖 -->
	<script src="https://cdn.bootcdn.net/ajax/libs/three.js/0.144.0/three.min.js"></script>
	<!-- threejs轨道控制器 -->
	<script src="https://cdn.jsdelivr.net/npm/three@0.144.0/examples/js/controls/OrbitControls.js"></script>
	<script type="text/javascript">
		var scene, // 场景
		    camera, // 摄像机
		    renderer, // 渲染器
		    controls, // 轨道控制器
		    boxMesh; // 正方体
		
		// 初始化场景
		function initScene() {
		  scene = new THREE.Scene();
		};
		// 初始化摄像机
		function initCamera() {
		  camera = new THREE.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 0.1, 1000);
		  scene.add(camera);
		};
		// 加载 模型
		function loaderCarModel() {
		  const boxShape = new THREE.BoxGeometry(1,1,1);
		  const boxMaterical = new THREE.MeshBasicMaterial({color: 0xffff00 });
		  const boxMesh = new THREE.Mesh(boxShape, boxMaterical);
		  scene.add(boxMesh);
		  // boxMesh.position.set(0, 0, 3);
		};
		// 添加fps提示
		function initStatus() {
		  stats = new Stats();
		  //设置统计模式
		  // stats.setMode(); // 0: fps, 1: ms 2: memory
		  //统计信息显示在左上角
		  stats.domElement.style.position = 'fixed';
		  stats.domElement.style.left = '0px';
		  stats.domElement.style.top = '0px';
		  //将统计对象添加到对应的<div>元素中
		  document.body.appendChild(stats.domElement);
		};
		// 初始化场景灯光
		function initLight() {
		  const light = new THREE.AmbientLight(0xFFFFFF);
		  scene.add(light);
		};
		/**
		 * 设置控制器的最小,最大视野
		 * 控制器的可选属性, 与所选择的摄像机类型有关
		 */
		function initControlerView(){
		  controls = new THREE.OrbitControls(camera, renderer.domElement);
		  controls.minDistance = 3; // 能够将相机向内移动多少(仅适用于PerspectiveCamera);其默认值为0。
		  controls.maxDistance = 30; // 能够将相机向外移动多少(仅适用于PerspectiveCamera);其默认值为Infinity。
		};
		// 初始化渲染器
		function initRenderer() {
		  renderer = new THREE.WebGLRenderer();
		  // renderer.setClearAlpha(0.0);
		  renderer.setSize(window.innerWidth, window.innerHeight);
		  document.body.appendChild(renderer.domElement);
		};
		// 渲染函数
		function animate() {
		    requestAnimationFrame(animate);
		    controls.update();
		
		    renderer.render( scene, camera );
		};
		// 主函数
		function main() {
		  // 1.新建场景
		  initScene();
		
		  // 2.新建照相机, 把照相机添加到场景中(照相机也是特殊的物体)
		  initCamera();
		
		  // 3.新建物体(形状,材质), 把物体添加到场景中
		  loaderCarModel();
		  camera.position.set(0,15,15); // 设置相机的位置, 至关重要; 默认 scene.add(), 会将物体添加到 (0,0,0)
		  // 初始化场景灯光
		  initLight();
		
		  // 4.新建渲染器, 设置渲染器的大小; 把渲染器的的DOM节点挂载倒视图
		  initRenderer();
		  initControlerView(); // 添加轨道控制器
		
		  // 5.启动渲染器, 请求下一帧的动画
		  animate();
		
		};
		
		/** 启动主函数 **/
		main();
	</script>
</html>


2_addControler

# 添加辅助坐标系

添加辅助坐标系

  • 参考链接
    • Threejs 辅助坐标系
      • https://threejs.org/docs/index.html?q=ax#api/zh/helpers/AxesHelper

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>添加辅助坐标系</title>
		<style type="text/css">
			* {
				padding: 0;
				margin: 0;
			}
		</style>
	</head>
	<body>
	</body>
	<!-- threejs基础包依赖 -->
	<script src="https://cdn.bootcdn.net/ajax/libs/three.js/0.144.0/three.min.js"></script>
	<!-- 挂载相关提示信息的状态组件 -->
	<script src="https://cdn.jsdelivr.net/npm/three@0.144.0/examples/js/libs/stats.min.js"></script>
	<!-- threejs轨道控制器 -->
	<script src="https://cdn.jsdelivr.net/npm/three@0.144.0/examples/js/controls/OrbitControls.js"></script>
	<script type="text/javascript">
		var scene, // 场景
		    camera, // 摄像机
		    renderer, // 渲染器
		    controls, // 轨道控制器
		    stats, // 统计信息
		    boxMesh; // 正方体
		
		// 添加fps提示
		function initStatus() {
		  const stats = new Stats();
		  //设置统计模式
		  // stats.setMode(); // 0: fps, 1: ms 2: memory
		  //统计信息显示在左上角
		  stats.domElement.style.position = 'fixed';
		  stats.domElement.style.left = '0px';
		  stats.domElement.style.top = '0px';
		  //将统计对象添加到对应的<div>元素中
		  document.body.appendChild(stats.domElement);
		  return stats;
		};
		function loaderCarModel () {
		  const boxShape = new THREE.BoxGeometry(1,1,1);
		  const boxMaterical = new THREE.MeshBasicMaterial({color: 0xffff00 });
		  boxMesh = new THREE.Mesh(boxShape, boxMaterical);
		  scene.add(boxMesh);
		};
		// 渲染函数
		function animate() {
		    requestAnimationFrame(animate);
		    stats.update();
		    controls.update();
		
		    boxMesh.position.x += 0.01;
		    camera.lookAt(boxMesh.position);
		    if(boxMesh.position.x > 5) {
		      boxMesh.position.x = 0;
		    }
		
		    renderer.render( scene, camera );
		};
		// 主函数
		function main() {
		  // 1.新建场景
		  scene = new THREE.Scene();
		
		  // 2.新建照相机, 把照相机添加到场景中(照相机也是特殊的物体)
		  camera = new THREE.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 0.1, 1000);
		  scene.add(camera);
		
		  // 3.新建物体(形状,材质), 把物体添加到场景中
		  loaderCarModel();
		  // 添加灯光
		  const light = new THREE.AmbientLight(0xFFFFFF);
		  scene.add(light);
		
		  camera.position.set(5, 5, 5); // 设置相机的位置, 至关重要; 默认 scene.add(), 会将物体添加到 (0,0,0)
		
		  // 4.新建渲染器, 设置渲染器的大小
		  renderer = new THREE.WebGLRenderer({
		    alpha: true,
		    antialias: true,
		  });
		  // renderer.setClearAlpha(0.0);
		  renderer.setSize(window.innerWidth, window.innerHeight);
		
		  // 5.把渲染器的的DOM节点挂载倒视图
		  document.body.appendChild(renderer.domElement);
		
		  controls = new THREE.OrbitControls(camera, renderer.domElement); // 添加轨道控制器
		  stats = initStatus(); //添加fps提示
		
		  // 添加辅助坐标系
		  const axesHelper = new THREE.AxesHelper(10);
		  scene.add(axesHelper);
		
		  // 6.启动渲染器, 请求下一帧的动画
		  animate();
		
		};
		
		/** 启动主函数 **/
		main();
	</script>
</html>


4_addAxesHelper

# *大模型的解决思路

# 加载方面
>模型压缩
https://blog.csdn.net/qq_26887683/article/details/121694689
http://www.xiaobaigis.com/Home/WebArticle?ID=144
nodejs库 gltf-pipeline进行压缩
	google draco 减少顶点坐标、顶点纹理坐标等信息的位数,以减少数据的存储量;
在线模型压缩  https://gltf.report

模型分片
	毕安格BIM模型轻量化
# 渲染方面

参考资料

  1. https://juejin.cn/post/6844903823496986631 2.限制渲染的帧率
Last Updated: 10/15/2022, 8:33:39 AM
Powered By Valine
v1.5.2
起风了
宋姿璇